var gLastPhraseId;

// Show the text at the given src (from the SMIL reference) then call the
// continuation function (e.g. play audio.)
// This is is necessary because we cannot highlight text before the document
// was loaded, and we cannot block or yield while waiting for the document to
// load.
function showTextThen(src, continuation)
{
	//this object will make URIs from local files
	var fileProtocolHandler = Components
    .classes["@mozilla.org/network/protocol;1?name=file"]
    .createInstance(Components.interfaces.nsIFileProtocolHandler);
	var requestedUri = fileProtocolHandler.newFileURI(src);
  	var target = getTarget(src.path);
  	// Get a tab in which to display the HTML content. If the document is new,
  	// then we should delay the highlighting by waiting for the document to
  	// load completely, otherwise we can go on.
  	// TODO: better check that this is the actual document that we were
  	// waiting for, and add a timeout to not wait indefinitely if something
  	// goes wrong.
	var delay = getDAISYTab(stripTarget(requestedUri.spec));
	if (delay) 
	{
	    var delayed = function(event) 
		{
			if (event.originalTarget instanceof HTMLDocument) 
			{
				window.removeEventListener("load", delayed, true);
	        	highlightThen(target, continuation);
	
			    window.onclick = handleClicks;
	      	}
	    };
		window.addEventListener("load", delayed, true);
	} 
	else 
	{
		highlightThen(target, continuation);
	}
}

// Highlight the text in the document that now has the focus, then call the
// continuation function.
function highlightThen(target, continuation)
{
 	unhighlight(gLastPhraseId);
	gLastPhraseId = target;
	highlight(target);
	continuation();
}

function highlight(target)
{
	if (target == "") return;
		
	//get the document, highlight the element, blah blah
	var doc = gBrowser.selectedBrowser.contentWindow.document;
	var phrase = doc.getElementById(target);

	if (phrase)
	{
		phrase.style.backgroundColor = "yellow";
		phrase.scrollIntoView();
	}
	// else alert("can't locate phrase with id " + target);
}
function unhighlight(target)
{
	if (target == "") return;
	
	var doc = gBrowser.selectedBrowser.contentWindow.document;
	var phrase = doc.getElementById(target);
	
	if (phrase)
	{
		phrase.style.backgroundColor = "";
	}
}
function getTarget(filePathAsString)
{
	var idx = filePathAsString.indexOf("#");
	if (idx != -1) return filePathAsString.substring(idx+1);
	else return "";
}

function stripTarget(filePathAsString)
{
	var idx = filePathAsString.indexOf("#");
	if (idx != -1) return filePathAsString.substring(0, idx);
	else
	{
		//check for stupid escaped hash signs
		idx = filePathAsString.indexOf("%23");
		if (idx != -1) return filePathAsString.substring(0, idx);
		else return filePathAsString;
	}
}

// Attribute to set on a tab to identify its DAISYness.
const DAISY_TAB_ATTR = "daisy-tab";

// TODO: close the tab and hide the sidebar.
function closeDAISYTab()
{
	var delay = false;
  	var wm = Components
    	.classes["@mozilla.org/appshell/window-mediator;1"]
    	.getService(Components.interfaces.nsIWindowMediator);
	var browsers = wm.getEnumerator("navigator:browser");
  	for (var found = false, index = 0, browser = browsers.getNext().getBrowser();
    	index < browser.mTabContainer.childNodes.length && !found;
    	index++) 
    {
        // Get the next tab
	    var currentTab = browser.mTabContainer.childNodes[index];
	    // Does this tab contain our custom attribute?
	    if (currentTab.hasAttribute(DAISY_TAB_ATTR)) 
		{
			// Yes--select and remove it.
	      	browser.selectedTab = currentTab;
            browser.removeCurrentTab();
            // Toggle sidebar too
            var sidebar = document.getElementById("sidebar") ||
                parent.document.getElementById("sidebar");
            if (sidebar.docShell != null)
            {
                toggleSidebar("togglesidebar-cmd");
            }
        }
    }
}

// Get the dedicated DAISY tab (or create it if it doesn't exist) to display
// the HTML content in. Return a flag set to true if the caller should wait
// for the document to load, false otherwise (i.e. the document was already
// loaded in the tab.)
// TODO: better handle multiple browsers/no browser.
// TODO: if we load a non-DAISY document in the tab, it should lose its
// attribute so that it is not replaced when DAISY playback is resumed.
// From http://developer.mozilla.org/en/docs/Code_snippets:Tabbed_browser
function getDAISYTab(url)
{
	var delay = false;
  	var wm = Components
    	.classes["@mozilla.org/appshell/window-mediator;1"]
    	.getService(Components.interfaces.nsIWindowMediator);
	var browsers = wm.getEnumerator("navigator:browser");
  	for (var found = false, index = 0, browser = browsers.getNext().getBrowser();
    	index < browser.mTabContainer.childNodes.length && !found;
    	index++) 
    {
        // Get the next tab
	    var currentTab = browser.mTabContainer.childNodes[index];
	    // Does this tab contain our custom attribute?
	    if (currentTab.hasAttribute(DAISY_TAB_ATTR)) 
		{
			// Yes--select and focus it.
	      	browser.selectedTab = currentTab;
	      	browser.focus();
	      	if (stripTarget(browser.currentURI.spec) != url) 
			{
	        	browser.loadURI(url, null, null);
	        	delay = true;
	      	}
	      	// Focus *this* browser in case another one is
	      	// currently focused
	      	found = true;
        }
    }
  	if (!found) 
	{
		// Our tab isn't open. Open it now.
	    var browserEnumerator = wm.getEnumerator("navigator:browser");
	    var browser = browserEnumerator.getNext().getBrowser(); 
	    // Create tab
	    var newTab = browser.addTab(url);
	    delay = true;
	    newTab.setAttribute(DAISY_TAB_ATTR, "");
	    // Focus tab
	    browser.selectedTab = newTab;
	    // Focus *this* browser in case another one is
	    // currently focused
	    browser.focus();
  	}
	return delay;
}
